/*
 * Project Name: jmax
 * File Name: OperationManager.java
 * Copyright: Copyright(C) 1985-2015 ZKTeco Inc. All rights reserved.
 */
package com.xdtech.hotel.protocol.manager;

import java.util.Collection;
import java.util.List;

import org.apache.commons.lang.StringUtils;

import javassist.expr.NewArray;

import com.xdtech.common.utils.JsonUtil;
import com.xdtech.hotel.monitor.ComponentInfo;
import com.xdtech.hotel.monitor.RoomMonitorInfo;
import com.xdtech.hotel.protocol.cmd.CmdManager;
import com.xdtech.hotel.protocol.util.SocketClientUtils;
import com.xdtech.hotel.protocol.util.WiegandUtils;
import com.xdtech.hotel.protocol.vo.Ac;
import com.xdtech.hotel.protocol.vo.Card;
import com.xdtech.hotel.protocol.vo.Dimmer;
import com.xdtech.hotel.protocol.vo.Music;
import com.xdtech.hotel.protocol.vo.Node;
import com.xdtech.hotel.protocol.vo.RCUDevice;
import com.xdtech.hotel.protocol.vo.Scene;
import com.xdtech.hotel.protocol.vo.Time;
import com.xdtech.hotel.protocol.vo.Tv;
import com.xdtech.hotel.util.HotelConstants;
import com.xdtech.hotel.util.RedisUtils;
import com.xdtech.hotel.vo.DeviceItem;
import com.xdtech.hotel.vo.DeviceLinkItem;
import com.xdtech.hotel.vo.DeviceLinkOptionItem;
import com.xdtech.hotel.vo.RoomItem;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

/**
 * TODO 一句话功能简述，请确保和下面的block tags之间保留一行空行
 * <p>
 * TODO 功能详细描述，若不需要请连同上面的p标签一起删除
 * 
 * @author max.zheng
 * @version TODO 添加版本
 * @see 相关类或方法，不需要请删除此行
 * @since 2015-4-9 上午11:40:53
 */
public class OperationManager
{
//	{
//		“SN” : “ 123456789”，
//		“function”:[
//			 { “music” :[
//				{ “id”: “0”， #可选参数：0,1,2,3,4,5,6,7,8
//				 “cmd”: “w”, # 可选参数：w/r ， w—写数据，r-- 读数据
//				 “power”: “on”， #可选参数：on/off； on—开，off--关音乐
//				 “volume”: “20”， #可选参数：0% - 100% 音量
//				 “channel”: “0” #可选参数：0-10 频道，暂不用
//				}
//				]
//			 }
//		]
//	}
	/**
	 * 音乐操作
	 * 
	 * @author max.zheng
	 * @since 2015-4-9 上午11:42:25
	 * @param sn
	 * @param value
	 */
	public static void operationComponent(String sn,OperationOption operationOption) {
//		JSONObject musicJson = createOperationJson(sn, operationOption);
//		RoomItem roomItem = RoomMonitor.getRoomItemBySn(sn);
//		JSONObject data = new JSONObject();
//		data.put("ip", roomItem.getDeviceIp());
//		data.put("port", roomItem.getDevicePort());
//		data.put("cmd", musicJson.toString());
//		CmdManager.addCmd(data.toString());
	}
	
	public static void createOperationCmd(String ip,int port,String cmd) {
		JSONObject data = new JSONObject();
		data.put("ip", ip);
		data.put("port", port);
		data.put("cmd", cmd);
		CmdManager.addCmd(data.toString());
	}
	
	
	
	public static JSONObject createOperationJson(String sn,OperationOption operationOption) {
		JSONObject json = new JSONObject();
		json.put("SN", sn);
		JSONArray jsonArray = new JSONArray();
		jsonArray.add(createOperationContent(operationOption));
		json.put("function", jsonArray);
		return json;
	}
	
	public static JSONObject createOperationContent(OperationOption operationOption) {
		JSONArray jsonArrayc = new JSONArray();
		JSONObject jsonc = new JSONObject();
		if (HotelConstants.COMPONENT_MUSIC.equals(operationOption.getType())) {
			jsonc.put("id", operationOption.getId());
			jsonc.put("cmd", operationOption.getCmd());
			jsonc.put("power", operationOption.getPower());
			jsonc.put("volume", operationOption.getVolume());
		}else if (HotelConstants.COMPONENT_CARD.equals(operationOption.getType())) {
			jsonc.put("id", operationOption.getId());
			jsonc.put("cmd",  operationOption.getCmd());
			jsonc.put("method", operationOption.getMethod());
			jsonc.put("data", operationOption.getData());
		}
		
		jsonArrayc.add(jsonc);
		JSONObject jsonObject = new JSONObject();
		jsonObject.put(operationOption.getType(), jsonArrayc);
		return jsonObject;
	}
	
	public static void main(String[] args)
	{
		JSONObject json = new JSONObject();
		json.put("SN", "1234567");
		JSONArray jsonArray = new JSONArray();
//		jsonArray.add(createOperationContent("music", "30"));
		json.put("function", jsonArray);
		
		System.out.println(json);
	}



	/**
	 * 通用命令测试
	 * @author max.zheng
	 * @create 2015-4-9下午11:32:30
	 * @modified by
	 * @param createItem
	 * @param deviceLinkItem
	 * @param deviceLinkOptionItems
	 * @return
	 */
	public static JSONObject createCmdJson(DeviceItem deviceItem,
			DeviceLinkItem deviceLinkItem,
			List<DeviceLinkOptionItem> deviceLinkOptionItems) {
		JSONObject json = new JSONObject();
		json.put("SN", deviceItem.getSn());
		JSONArray jsonArray = new JSONArray();
		
		JSONArray jsonArrayc = new JSONArray();
		JSONObject jsonc = new JSONObject();
		for (DeviceLinkOptionItem deviceLinkOptionItem : deviceLinkOptionItems) {
			jsonc.put(deviceLinkOptionItem.getName(), deviceLinkOptionItem.getVal());
		}
		jsonArrayc.add(jsonc);
		JSONObject jsonObject = new JSONObject();
		jsonObject.put(deviceLinkItem.getLtype(), jsonArrayc);
		
		jsonArray.add(jsonObject);
		json.put("function", jsonArray);
		return json;
	}
	
	
	/**
	 * 
	 * 创建write命令给设备统一入口
	 * @author max.zheng
	 * @create 2015-5-10下午9:38:16
	 * @modified by
	 * @param sn      设备序列号
	 * @param type    操作类型
	 * @param cmdData 发送命令数据内容，为空的话系统设置
	 * @return
	 */
	public static JSONObject createWrite(String sn,String type,String cmdData) {
		JSONObject json = new JSONObject();
		json.put("SN", sn);
		JSONArray jsonArray = new JSONArray();
		
		JSONArray jsonArrayc = new JSONArray();
		String content = "";
		if (StringUtils.isNotBlank(cmdData)) {
			content = cmdData;
		}else {
			if (HotelConstants.DEV_NODE_CONTROL.equals(type)) {
				content = JsonUtil.getJsonStr(new Node(HotelConstants.NODE_LIGHTS,"1", "1", "blink", "1", "1").createCmdNode());
			}else if (HotelConstants.DEV_DIMMER_CONTROL.equals(type)) {
				content = JsonUtil.getJsonStr(new Dimmer("0", "0", "on", "0", "0", "0"));
			}else if (HotelConstants.DEV_AC_CONTROL.equals(type)) {
				content = JsonUtil.getJsonStr(new Ac("0", "0", "on", "auto", "low", "20"));
			}else if (HotelConstants.DEV_TV_CONTROL.equals(type)) {
				content = JsonUtil.getJsonStr(new Tv("0", "0", "on", "20", "0", "0", "next"));
			}else if (HotelConstants.DEV_MUSIC_CONTROL.equals(type)) {
				content = JsonUtil.getJsonStr(new Music("0", "0", "on", "20", "0","0", "next"));
			}else if (HotelConstants.DEV_CARD_CONTROL.equals(type)) {
				content = JsonUtil.getJsonStr(new Card("add", "1", "12345678"));
			}else if (HotelConstants.DEV_SCENE_CONTROL.equals(type)) {
				content = JsonUtil.getJsonStr(new Scene("1"));
			}else if (HotelConstants.DEV_TIME_CONTROL.equals(type)) {
				content = JsonUtil.getJsonStr(new Time());
			}
		}
		
		jsonArrayc.add(content);
		JSONObject jsonObject = new JSONObject();
		jsonObject.put(type, jsonArrayc);
		
		jsonArray.add(jsonObject);
		json.put("write", jsonArray);
		return json;
	}

	
	public static boolean sendWriteCard(String sn,String operation,String type,String cardNo) {
		String cardData = cardNo;//WiegandUtils.setCardToWg26(cardNo);
		String content = JsonUtil.getJsonStr(new Card(operation, type, cardData));
		return sendWriteCmdToDev(sn, "card", content);
	}
	/**
	 * 
	 * 发送命令操作统一接口
	 * 
	 * @author max.zheng
	 * @create 2015-5-10下午9:51:06
	 * @modified by
	 * @param sn
	 * @param type
	 * @param cmdData
	 * @return
	 */
	public static boolean sendWriteCmdToDev(String sn,String type,String cmdData) {
		JSONObject jsonObject = OperationManager.createWrite(sn, type, cmdData);
		RCUDevice device = DeviceMonitor.monitorDevices.get(sn);
		String result = SocketClientUtils.sendData(sn,device.getIp(), Integer.valueOf(device.getPort()), jsonObject.toString());
		//响应返回
    	RedisUtils.addPostCmdToDevcie(sn, cmdData+"#"+result);
		return result.contains("\"success\":\"true\"");
	}

	/**
	 * 
	 * @author max.zheng
	 * @create 2015-4-28下午10:49:43
	 * @modified by
	 * @param sn
	 * @param type
	 * @return
	 */
	public static JSONObject createRead(String sn, String type) {
		JSONObject json = new JSONObject();
		json.put("SN", sn);
		JSONArray jsonArray = new JSONArray();
		
		JSONObject jsonObject = addReadComponent(type,new ComponentInfo(type, "0", "1", "1"));
		jsonArray.add(jsonObject);
		json.put("read", jsonArray);
		return json;
	}

	/**
	 * 
	 * @author max.zheng
	 * @create 2015-5-12下午10:52:56
	 * @modified by
	 * @param type
	 * @return
	 */
	private static JSONObject addReadComponent(String type,ComponentInfo componentInfo) {
		JSONArray jsonArrayc = new JSONArray();
		JSONObject readJson = new JSONObject();
		if (HotelConstants.DEV_NODE_CONTROL.equals(type)
		  ||HotelConstants.DEV_DIMMER_CONTROL.equals(type)
		  ||HotelConstants.DEV_AC_CONTROL.equals(type)
		  ||HotelConstants.DEV_TV_CONTROL.equals(type)
		  ||HotelConstants.DEV_MUSIC_CONTROL.equals(type)) {
			readJson.put("addr", componentInfo.getAddr());
			readJson.put("channel", componentInfo.getChannel());
			
		}else if (HotelConstants.DEV_CARD_CONTROL.equals(type)) {
			readJson.put("card", "0");
		}else if (HotelConstants.DEV_SCENE_CONTROL.equals(type)) {
			readJson.put("scene", "0");
		}else if (HotelConstants.DEV_TIME_CONTROL.equals(type)) {
			readJson.put("time", "0");
		}
		jsonArrayc.add(readJson.toString());
		JSONObject jsonObject = new JSONObject();
		jsonObject.put(type, jsonArrayc);
		return jsonObject;
	}
	
	/**
	 * 
	 * @author max.zheng
	 * @create 2015-4-28下午10:49:43
	 * @modified by
	 * @param sn
	 * @param type
	 * @return
	 */
	public static String sendReadCmdToDevice(String sn, Collection<ComponentInfo> componentInfos) {
		JSONObject json = new JSONObject();
		json.put("SN", sn);
		JSONArray jsonArray = new JSONArray();
		for (ComponentInfo componentInfo : componentInfos) {
			JSONObject jsonObject = addReadComponent(componentInfo.getType(),componentInfo);
			jsonArray.add(jsonObject);
		}
		
		json.put("read", jsonArray);
		
		RCUDevice device = DeviceMonitor.monitorDevices.get(sn);
		String result = SocketClientUtils.sendData(sn,device.getIp(), Integer.valueOf(device.getPort()), json.toString());
		return result;
	}

	/**
	 * 
	 * @author max.zheng
	 * @create 2015-5-25下午8:29:36
	 * @modified by
	 * @param ip
	 * @param valueOf
	 * @param cmd
	 * @return
	 */
	public static String sendData(String sn,String ip, Integer port, String cmd) {
		String rs = SocketClientUtils.sendData(sn,ip, port, cmd);
		//响应返回
    	RedisUtils.addPostCmdToDevcie(sn, cmd+"#"+rs);
		return rs;
	}
	
	public static String secondSendData(String sn,String ip, Integer port, String cmd) {
		String rs = SocketClientUtils.sendData(sn,ip, port, cmd);
		return rs;
	}
	
	//测试
	public static boolean sendCmdToDev(String sn,String cmdData) {
		RCUDevice device = DeviceMonitor.monitorDevices.get(sn);
		String result = SocketClientUtils.sendData(sn,device.getIp(), Integer.valueOf(device.getPort()), cmdData);
		//响应返回
    	RedisUtils.addPostCmdToDevcie(sn, cmdData+"#"+result);
		return result.contains("\"success\":\"true\"");
	}
	//异步批量发卡
	public static void asyncWriteCards(final String cardType,final String cardNo,final List<RoomItem> roomItems) {
		new Thread(new Runnable() {
			@Override
			public void run() {
				for (RoomItem roomItem : roomItems) {
					try {
						sendWriteCard(roomItem.getDeviceSn(), "add", cardType, cardNo);
					} catch (Exception e) {
						System.out.println("异步发送卡号失败");
						e.printStackTrace();
					}
					
					
				}
			}
		}, "AsyncSendCardsThread").start();
	}
}
